package com.rogan.rpc.rpcserver;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Map;

import com.rogan.rpc.message.JSONMessageProtocol;
import com.rogan.rpc.message.MessageProtocol;
import com.rogan.rpc.message.Request;
import com.rogan.rpc.message.Response;
import com.rogan.rpc.message.Status;

public class RpcServer {
    private int port;
    private String protocol;
    private ServiceRegister serviceRegister;
	public int getPort() {
		return port;
	}
	public void setPort(int port) {
		this.port = port;
	}
	public String getProtocol() {
		return protocol;
	}
	public void setProtocol(String protocol) {
		this.protocol = protocol;
	}
	public ServiceRegister getServiceRegister() {
		return serviceRegister;
	}
	public void setServiceRegister(ServiceRegister serviceRegister) {
		this.serviceRegister = serviceRegister;
	}
	
	public void start() throws IOException, ClassNotFoundException {
		RequestHandler handler = new RequestHandler();
		byte[] data = null;
		// 打开socketserver
		ServerSocket serverSocket = new ServerSocket(8081);
		while (true) {
			Socket socket = serverSocket.accept();
			OutputStream output = socket.getOutputStream();
			InputStream input = socket.getInputStream();
			
			byte[] binput = new byte[1024];
			String rs="";
			int i = -1;
			while ( (i= input.read(binput)) >0) {
				rs += new String(binput);
				if (i < 1024) {
					break;
				}
			}
			 System.out.println(rs);
			MessageProtocol protocol = new JSONMessageProtocol();
			Request request = protocol.unmarchallingRequest(rs.getBytes());
		 
			Map<String, String> headers = request.getHeaders();
			String method = request.getMethod();
			Object[] parameters = request.getParameters();
			Class<?>[] parameterTypes = request.getParameterTypes();
			String serviceName = request.getServiceName();
			
			ServiceObject service = this.serviceRegister.getServiceObject(serviceName);
			Class<?> clazz = service.getObj().getClass();
			Method method1;
			Response response = new Response();
			try {
				method1 = clazz.getMethod( method, parameterTypes);
				Object result = method1.invoke(clazz.newInstance(), parameters);
				
				response.setReturnType(result.getClass());
				response.setReturnValue(result);
				response.setHeaders(headers);
				response.setStatus(Status.SUCEESS);
			 
				byte[] bout = protocol.marshallingRespose(response);
			 
				
				output.write(bout);
				output.flush();
				 
				socket.close();
			} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) {
				e.printStackTrace();
				response.setStatus(Status.ERROR);
			}  
			
			
		}
		
		 
	}
	
	public void stop() {
		
	}
	
	 
}
